8.2: Menjadwalkan Alarm

Materi:

Anda sudah mengetahui cara menggunakan penerima siaran untuk membuat aplikasi merespons kejadian sistem bahkan bila aplikasi sedang tidak dijalankan. Dalam bab ini, Anda akan mempelajari cara menggunakan alarm untuk menjadwalkan tugas selama waktu tertentu, baik aplikasi dijalankan pada saat alarm disetel untuk aktif maupun tidak. Alarm bisa untuk sekali penggunaan atau berulang. Misalnya, Anda bisa menggunakan alarm berulang untuk menjadwalkan pengunduhan setiap hari pada waktu yang sama.

Untuk membuat alarm, gunakan kelas AlarmManager . Alarm di Android memiliki karakteristik berikut:

  • Alarm memungkinkan Anda mengirim maksud pada waktu atau interval yang disetel. Anda bisa menggunakan alarm bersama penerima siaran untuk memulai layanan dan menjalankan operasi lainnya.
  • Alarm beroperasi di luar aplikasi, sehingga Anda bisa menggunakannya untuk memicu kejadian atau tindakan bahkan saat aplikasi sedang tidak dijalankan, dan bahkan jika perangkat nonaktif.
  • Bila digunakan dengan benar, alarm bisa membantu Anda meminimalkan kebutuhan sumber daya aplikasi. Misalnya, Anda bisa menjadwalkan operasi tanpa mengandalkan timer atau terus menjalankan layanan latar belakang.

Bila tidak menggunakan alarm:

  • Untuk kejadian pengaturan waktu seperti tick dan waktu tunggu, dan untuk operasi berwaktu yang dipastikan terjadi selama masa aplikasi Anda, gunakan kelas Handler bersama Timer dan Thread. Pendekatan ini memberi Android kontrol yang lebih baik atas sumber daya sistem daripada jika Anda menggunakan alarm.
  • Untuk operasi sinkronisasi server, gunakan SyncAdapter bersama Google Cloud Messaging Service.
  • Untuk tugas yang bisa menunggu hingga kondisi memungkinkan, seperti bila perangkat terhubung ke WiFi dan sedang mengisi daya (misalnya, memperbarui informasi cuaca atau kabar berita), Anda mungkin tidak ingin menggunakan alarm. Untuk tugas ini di perangkat API 21+, pertimbangkan penggunaan JobScheduler, yang akan Anda pelajari di pelajaran mendatang.

Tipe alarm

Ada dua tipe alarm umum di Android: alarm waktu tempuh riil serta alarm jam real-time (RTC), dan keduanya menggunakan objek PendingIntent .

Alarm waktu tempuh riil

Alarm waktu tempuh riil menggunakan waktu, dalam milidetik, sejak perangkat melakukan booting. Alarm waktu tempuh riil tidak terpengaruh oleh zona waktu, sehingga bekerja dengan baik untuk alarm berdasarkan waktu yang telah ditempuh. Misalnya, gunakan alarm waktu tempuh riil untuk alarm yang aktif setiap setengah jam.

Kelas AlarmManager menyediakan dua tipe alarm waktu tempuh riil:

  • ELAPSED_REALTIME: Akan memicu PendingIntent berdasarkan pada jumlah waktu sejak perangkat booting, namun tidak membangunkan perangkat. Waktu tempuh menyertakan waktu selama perangkat sedang tidur. Semua alarm berulang akan terpicu bila perangkat bangun pada waktu berikutnya.
  • ELAPSED_REALTIME_WAKEUP: Akan memicu PendingIntent setelah jangka waktu yang ditetapkan berlalu sejak perangkat booting, yang membangunkan CPU perangkat jika layar mati. Gunakan alarm ini sebagai ganti ELAPSED_REALTIME jika aplikasi Anda memiliki dependensi waktu, misalnya jika memiliki jendela terbatas selama menjalankan operasi.

Alarm jam real-time (RTC)

Alarm jam real-time (RTC) adalah alarm berbasis jam yang menggunakan Coordinated Universal Time (UTC). Hanya pilih alarm RTC dalam tipe situasi ini:

  • Anda perlu alarm yang dipicu pada waktu tertentu dalam sehari.
  • Waktu alarm bergantung pada lokal saat ini.

Aplikasi dengan alarm berbasis jam mungkin tidak berfungsi dengan baik di seluruh lokal, karena mungkin akan terpicu pada waktu yang salah. Dan jika pengguna mengubah setelan waktu perangkat, maka hal itu bisa menyebabkan perilaku yang tidak diharapkan di aplikasi Anda.

Kelas AlarmManager menyediakan dua tipe alarm RTC:

  • RTC: Akan memicu maksud yang menunggu pada waktu yang ditetapkan, namun tidak membangunkan perangkat. Semua alarm berulang akan terpicu bila perangkat bangun pada waktu berikutnya.
  • RTC_WAKEUP: Akan memicu maksud yang menunggu pada waktu yang ditetapkan, yang membangunkan CPU perangkat jika layar mati.

Praktik terbaik alarm

Alarm memengaruhi cara aplikasi Anda menggunakan (atau menyalahgunakan) sumber daya sistem. Misalnya, bayangkan aplikasi populer yang menyinkronkan dengan server. Jika operasi sinkronisasi berdasarkan pada waktu jam dan setiap instance aplikasi menghubungkan ke server pada waktu yang sama, beban pada server bisa mengakibatkan waktu respons tertunda atau bahkan kondisi "denial of service".

Untuk menghindari masalah ini dan masalah lainya, ikuti praktik terbaik ini:

  • Tambahkan keacakan (jitter) ke permintaan jaringan yang terpicu akibat alarm berulang. Inilah satu cara untuk melakukannya:
    • Jadwalkan alarm pasti yang menjalankan suatu pekerjaan lokal. "Pekerjaan lokal" berarti sesuatu yang tidak menghubungi server melalui jaringan atau memerlukan data dari server.
    • Jadwalkan alarm terpisah yang berisi permintaan jaringan, dan setel alarm ini agar terpicu setelah periode waktu acak. Biasanya alarm kedua ini disetel oleh komponen apa pun yang menerima PendingIntent dari alarm pertama. (Anda juga bisa menyetel alarm ini pada waktu yang sama seperti alarm pertama.)
  • Pertahankan frekuensi alarm Anda tetap minimum.
  • Jangan bangunkan perangkat jika tidak diperlukan.
  • Gunakan pengaturan waktu yang paling tidak akurat untuk memungkinkan AlarmManager menjadi yang paling efisien. Misalnya, bila Anda menjadwalkan alarm berulang, gunakan setInexactRepeating() sebagai ganti setRepeating(). Untuk detailnya, lihat Menjadwalkan alarm berulang, di bawah ini.
  • Hindari mendasarkan alarm pada waktu jam dan gunakan ELAPSED_REALTIME untuk alarm berulang bila memungkinkan. Alarm berulang yang berdasarkan pada waktu pemicu akurat tidak akan menskalakan dengan baik.

Menjadwalkan alarm

Kelas AlarmManager memberi Anda akses ke layanan alarm sistem Android. AlarmManager memungkinkan Anda menyiarkan Intent pada waktu yang dijadwalkan, atau setelah interval tertentu.

Untuk menjadwalkan alarm:

  1. Panggil getSystemService(ALARM_SERVICE) untuk mendapatkan instance kelas AlarmManager .
  2. Gunakan salah satu metode set...() yang tersedia di AlarmManager (sebagaimana dijelaskan di bawah ini). Metode yang Anda gunakan bergantung pada apakah alarm telah menempuh waktu yang riil, atau RTC.

Semua metode AlarmManager.set...() menyertakan dua argumen:

Menjadwalkan alarm sekali-pakai

Untuk menjadwalkan satu alarm, gunakan salah satu metode berikut ini di instance AlarmManager :

  • set(): Untuk perangkat yang menjalankan API 19+, metode ini menjadwalkan satu alarm berwaktu tidak pasti, maksudnya, sistem akan menggeser alarm untuk meminimalkan membangunkan dan penggunaan baterai. Untuk perangkat yang menjalankan versi API lebih rendah, metode ini menjadwalkan alarm yang berwaktu pasti.
  • setWindow(): Untuk perangkat yang menjalankan API 19+, gunakan metode ini untuk menyetel jangka waktu untuk memicu alarm.
  • setExact(): Untuk perangkat yang menjalankan API 19+, metode ini memicu alarm pada waktu yang pasti. Gunakan metode ini hanya untuk alarm yang harus dipicu pada waktu yang pasti, misalnya jam alarm yang berdering pada waktu yang diminta. Alarm pasti akan mengurangi kemampuan OS untuk meminimalkan penggunaan baterai, jadi jangan menggunakannya jika tidak diperlukan.

Inilah contoh penggunaan set() untuk menjadwalkan alarm sekali-pakai:

alarmMgr.set(AlarmManager.ELAPSED_REALTIME,
             SystemClock.elapsedRealtime() + 1000*300,
             alarmIntent);

Dalam contoh ini:

  • Kelas type adalah ELAPSED_REALTIME, yang berarti bahwa ini adalah alarm waktu tempuh riil. Jika perangkat sedang tidak digunakan saat alarm dikirim, alarm tidak akan membangunkan perangkat.
  • Alarm dikirim 5 menit (300.000 milidetik) setelah metode dikembalikan.
  • alarmIntent adalah siaran PendingIntent berisi aksi yang akan dijalankan ketika alarm dikirim.
    Catatan: Untuk operasi pengaturan waktu seperti tick dan waktu tunggu, serta kejadian yang lebih dari sekali dalam satu menit, akan lebih mudah dan efisien menggunakan Penangan daripada alarm.

Istirahatkan dan Aplikasi Siaga

Perangkat API 23+ kadang-kadang masuk ke mode Istirahatkan atau Aplikasi Siaga untuk menghemat daya:

  • Mode Istirahatkan dipicu bila pengguna meninggalkan perangkat yang stekernya tidak terhubung dan tidak bergerak selama periode waktu tertentu, dengan layar dimatikan. Selama "masa pemeliharaan" singkat, sistem akan keluar dari Istirahatkan untuk memungkinkan aplikasi menyelesaikan aktivitas yang ditangguhkan, termasuk memicu alarm standar, kemudian kembali ke Istirahatkan. Mode Istirahatkan berakhir bila pengguna kembali ke perangkat mereka.
  • Mode Aplikasi Siaga dipicu pada aplikasi diam yang tidak digunakan baru-baru ini. Mode Aplikasi Siaga berakhir bila pengguna kembali ke aplikasi atau menghubungkan steker di perangkat.

Untuk menggunakan alarm dengan Istirahatkan dan Aplikasi Siaga:

  • Jika Anda memerlukan alarm yang terpicu saat perangkat berada dalam mode Istrahatkan atau Aplikasi Siaga tanpa menunggu masa pemeliharaan, gunakan setAndAllowWhileIdle() untuk alarm tidak pasti dan setExactAndAllowWhileIdle() untuk alarm pasti, atau setel alarm yang terlihat pengguna (API 21+).
  • Beberapa alarm bisa menunggu masa pemeliharaan, atau hingga perangkat keluar dari mode Istirahatkan atau Aplikasi Siaga. Untuk alarm ini, gunakan metode set() dan setExact() standar untuk mengoptimalkan daya tahan baterai.

Menjadwalkan alarm berulang

Anda juga bisa menggunakan AlarmManager untuk menjadwalkan alarm berulang, dengan menggunakan salah satu metode berikut:

  • setRepeating(): Sebelum Android 4.4 (API Level 19), metode ini akan membuat alarm berulang dengan waktu yang pasti. Pada perangkat yang menjalankan API 19 dan yang lebih tinggi, perilaku setRepeating() benar-benar seperti setInexactRepeating().
  • setInexactRepeating(): Metode ini membuat alarm tidak pasti berulang yang memungkinkan batch. Bila Anda menggunakan setInexactRepeating(), Android akan menyinkronkan alarm berulang untuk beberapa aplikasi dan memicunya pada waktu yang sama. Hal ini mengurangi jumlah total waktu yang digunakan sistem untuk membangunkan perangkat, sehingga mengurangi konsumsi daya baterai. Seperti pada API 19, semua alarm berulang adalah alarm tidak pasti.

Untuk mengurangi kemungkinan konsumsi daya baterai:

  • Jadwalkan alarm berulang menjadi sejarang mungkin.
  • Gunakan pengaturan waktu tidak pasti, yang memungkinkan sistem untuk menyatukan alarm dari aplikasi yang berbeda.

Catatan: meskipun setInexactRepeating() merupakan perbaikan atas setRepeating(), tetap saja bisa membebani server jika setiap instance aplikasi menghubungkan ke server pada waktu yang kurang lebih sama. Oleh karena itu, untuk permintaan jaringan, tambahkan beberapa keacakan pada alarm Anda, seperti yang dijelaskan dalam Praktik terbaik alarm.

Jika Anda benar-benar memerlukan alarm pasti yang berulang pada API 19+, setel alarm sekali-pakai dengan setExact() dan setel alarm berikutnya setelah alarm itu dipicu. Alarm kedua ini disetel oleh komponen apa pun yang menerima PendingIntent—biasanya layanan atau penerima siaran.

Inilah contoh penggunaan setInexactRepeating() untuk menjadwalkan alarm berulang:

alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
               calendar.getTimeInMillis(),
               AlarmManager.INTERVAL_FIFTEEN_MINUTES,
               alarmIntent);

Dalam contoh ini:

  • Dalam hal ini, type adalah RTC_WAKEUP, berarti alarm ini adalah alarm berbasis jam yang membangunkan perangkat bila alarm telah dikirim.
  • Kekerapan alarm pertama dikirim segera, karena calendar.getTimeInMillis() mengembalikan waktu saat ini sebagai UTC milidetik.
  • Setelah kekerapan pertama, alarm dikirim kurang lebih setiap 15 menit.

    Jika metodenya adalah setRepeating() sebagai ganti setInexactRepeating(), dan jika perangkat menjalankan versi API yang lebih rendah dari 19, alarm pasti dikirim setiap 15 menit.

    Nilai-nilai yang memungkinkan untuk argumen ini adalah INTERVAL_DAY, INTERVAL_FIFTEEN_MINUTES, INTERVAL_HALF_DAY, INTERVAL_HALF_HOUR, INTERVAL_HOUR.

  • alarmIntent adalah PendingIntent yang berisi aksi untuk dijalankan bila alarm telah dikirim. Maksud ini biasanya berasal dari IntentSender.getBroadcast().

Memeriksa alarm yang ada

Sering kali ada gunanya memeriksa apakah alarm sudah disetel. Misalnya, Anda mungkin ingin menonaktifkan kemampuan untuk menyetel alarm lain jika sudah ada alarm yang disetel.

Untuk memeriksa alarm yang ada:

  1. Buat PendingIntent yang berisi Intent serupa yang digunakan untuk menyetel alarm, namun kali ini menggunakan flag FLAG_NO_CREATE .

    Dengan FLAG_NO_CREATE, PendingIntent hanya dibuat jika sudah ada yang berisi Intent yang sama. Jika tidak maka permintaan akan mengembalikan nol.

  2. Periksa apakah PendingIntent adalah null:
    • Jika ini null, berarti alarm belum disetel.
    • Jika bukan null, maka PendingIntent sudah ada, berarti alarm telah disetel.

Misalnya, kode berikut akan mengembalikan true jika alarm yang dimuat dalam alarmIntent sudah ada:

boolean alarmExists =
 (PendingIntent.getBroadcast(this, 0,
       alarmIntent,
       PendingIntent.FLAG_NO_CREATE) != null);

Membatalkan alarm

Untuk membatalkan alarm, gunakan cancel() dan teruskan di PendingIntent. Misalnya:

alarmManager.cancel(alarmIntent);

Alarm yang terlihat pengguna ("jam alarm")

Untuk perangkat API 21+, Anda bisa menyetel jam alarm yang terlihat pengguna dengan memanggil setAlarmClock(). Aplikasi bisa mengambil jam alarm yang terlihat pengguna berikutnya yang disetel agar terpicu dengan memanggil getNextAlarmClock().

Jam alarm yang disetel dengan setAlarmClock() akan berfungsi, bahkan bila perangkat atau aplikasi dalam keadaan diam (serupa dengan setExactAndAllowWhileIdle()), yang membuat Anda sedekat mungkin dengan panggilan membangunkan yang pasti.

Praktik terkait

Latihan terkait dan dokumentasi praktik ada di Dasar-Dasar Developer Android: Praktik.

Ketahui selengkapnya

results matching ""

    No results matching ""